/**
 * 向指定元素添加触点移动事件监听，并且在触点抬起时移除事件监听
 *
 * @param {HTMLElement} el 需要添加触点移动事件监听的元素
 * @param {(this:HTMLElement, evt: TouchEvent) => any} handler 触点移动事件监听处理函数
 * @param {object} options 配置选项：
 * - addOptions 添加事件监听时使用的配置选项，默认为 `{ passive: true }`
 * - addTouchMoveOptions 添加触点移动（touchmove）事件监听时使用的配置选项，如果没有设置此选项，则使用 `addOptions` 选项的值
 * - addTouchEndOptions 添加触点抬起（touchend）事件监听时使用的配置选项，如果没有设置此选项，则使用 `addOptions` 选项的值
 * - removeOptions 移除事件监听时使用的配置选项，默认为 `undefined`
 * - removeTouchMoveOptions 移除触点移动（touchmove）事件监听时使用的配置选项，如果没有设置此选项，则使用 `removeOptions` 选项的值
 * - removeTouchEndOptions 移除触点抬起（touchend）事件监听时使用的配置选项，如果没有设置此选项，则使用 `removeOptions` 选项的值
 */
export const addTouchMoveEvtListener = (
  el: HTMLElement,
  handler: (this: HTMLElement, evt: TouchEvent) => any,
  options?: {
    addOptions?: boolean | AddEventListenerOptions
    addTouchMoveOptions?: boolean | AddEventListenerOptions
    addTouchEndOptions?: boolean | AddEventListenerOptions
    removeOptions?: boolean | EventListenerOptions
    removeTouchMoveOptions?: boolean | EventListenerOptions
    removeTouchEndOptions?: boolean | EventListenerOptions
  }
) => {
  const {
    addOptions,
    addTouchMoveOptions,
    addTouchEndOptions,
    removeOptions,
    removeTouchMoveOptions,
    removeTouchEndOptions
  } = { addOptions: { passive: true }, ...options }

  const handleEnd = () => {
    el.removeEventListener('touchmove', handler, removeTouchMoveOptions ?? removeOptions)
    el.removeEventListener('touchend', handleEnd, removeTouchEndOptions ?? removeOptions)
  }

  el.addEventListener('touchmove', handler, addTouchMoveOptions ?? addOptions)
  el.addEventListener('touchend', handleEnd, addTouchEndOptions ?? addOptions)
}

export type AddTouchMoveEvtListenerType = typeof addTouchMoveEvtListener
